/**
 *  Copyright 2002-2009 the original author or authors.
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */
package foo.bar.blog.web.extension;

import net.sourceforge.stripes.action.Resolution;
import net.sourceforge.stripes.controller.ExecutionContext;
import net.sourceforge.stripes.controller.Interceptor;
import net.sourceforge.stripes.controller.Intercepts;
import net.sourceforge.stripes.controller.LifecycleStage;
import net.sourceforge.stripes.integration.spring.SpringBean;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionCallback;
import org.springframework.transaction.support.TransactionTemplate;
import org.springframework.transaction.support.TransactionSynchronizationManager;

import javax.servlet.http.HttpServletRequest;

import foo.bar.blog.web.action.TransactionStatusAware;

/**
 * @author tmjee
 * @version $Date: 2009-06-06 13:26:52 +0000 (Sat, 06 Jun 2009) $ $Id$
 */
@Intercepts({LifecycleStage.BindingAndValidation, LifecycleStage.CustomValidation, LifecycleStage.EventHandling})
public class TransactionInterceptor implements Interceptor {

    private static final Log LOG = LogFactory.getLog(TransactionInterceptor.class);

    private TransactionTemplate transactionTemplate;

    public Resolution intercept(ExecutionContext executionContext) throws Exception {
            Resolution resolution = executionContext.proceed();
            // this will happens in both BindingAndVlidation and EventHandling cycles
            if (executionContext.getActionBeanContext().getValidationErrors().size() > 0) {
                rollbackTransaction(executionContext);
                if (executionContext.getLifecycleStage() == LifecycleStage.EventHandling) {
                    return executionContext.getActionBeanContext().getSourcePageResolution();
                }
            }
            return resolution;
    }

    protected void rollbackTransaction(ExecutionContext executionContext) {
        if (executionContext.getActionBean() instanceof TransactionStatusAware) {
            ((TransactionStatusAware)executionContext.getActionBean()).getCurrentTransactionStatus().setRollbackOnly();
        }
        else {
            throw new RuntimeException("ActionBean ["+executionContext.getActionBean()+"] is not TransactionStatusAware");
        }
    }

    @SpringBean("transactionTemplate")
    public void setTransactionTemplate(TransactionTemplate transactionTemplate) {
        this.transactionTemplate = transactionTemplate;
    }
}
